
//声明构造函数 Promise
function Promise(executor){
    const self = this;
    //状态属性
    self.promiseState = 'pending';
    //结果值属性
    self.promiseResult = null;
    //声明属性 
    self.callbacks = [];

    function resolve(value){
        if(self.promiseState !== 'pending') return;
        //1. 修改 promise 对象的状态
        self.promiseState = 'fulfilled';
        //2. 设置 promise 成功的结果值
        self.promiseResult = value;
        //执行成功的回调. 这里如何获取回调呢??
        self.callbacks.forEach(item => {
            //执行成功的回调
            item.onFulfilled(value);
        });
    }

    function reject(reason){
        if(self.promiseState !== 'pending') return;
        self.promiseState = 'rejected';
        self.promiseResult = reason;
        //执行失败的回调
        self.callbacks.forEach(item => {
            //执行成功的回调
            item.onRejected(reason);
        });
    }

    try{
        //执行器函数 executor 是同步调用的
        executor(resolve, reject);
    }catch(e){
        reject(e);
    }
}

//声明 Promise.prototype.then 方法
Promise.prototype.then = function(onFulfilled, onRejected){
    return new Promise((resolve, reject) => {
        //声明一个函数
        let callback = (type) => {
            //执行成功的回调
            let rs = type(this.promiseResult);
            //判断结果
            if(rs instanceof Promise){
                rs.then(v => {
                    resolve(v);
                }, r=>{
                    reject(r);
                })
            }else{
                resolve(rs);
            }
        }
        //执行成功回调
        if(this.promiseState === 'fulfilled'){
            callback(onFulfilled);     
        }
        //执行失败回调
        if(this.promiseState === 'rejected'){
            callback(onRejected);
        }
        //如果是pending状态
        if(this.promiseState === 'pending'){
            //这里不能执行回调, 要等到 promise 对象状态改变了以后, 才能执行回调
            //将回调保存起来.
            this.callbacks.push({
                onFulfilled: () => {
                    callback(onFulfilled);
                },
                onRejected: () => {
                    callback(onRejected);
                }
            });
        }
    });
}



